Bug 25451: time and date calculation in 32-bit
authorPlatonides <platonides@users.mediawiki.org>
Tue, 23 Nov 2010 18:25:00 +0000 (18:25 +0000)
committerPlatonides <platonides@users.mediawiki.org>
Tue, 23 Nov 2010 18:25:00 +0000 (18:25 +0000)
Follow up r75761. Now calculation is right (passes all tests)
on php 32 bits when using PHP >= 5.2
without prejudice to PHP 32/64 bits < 5.2 on the 32 bit range
(regardless of architecture)

includes/GlobalFunctions.php

index 80b15a3..7a01f20 100644 (file)
@@ -1986,6 +1986,8 @@ define( 'TS_ISO_8601_BASIC', 9 );
 function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
        $uts = 0;
        $da = array();
+       $strtime = '';
+       
        if ( $ts === 0 ) {
                $uts = time();
        } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
@@ -1997,10 +1999,11 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
        } elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) {
                # TS_UNIX
                $uts = $ts;
+               $strtime = "@$ts"; // Undocumented?
        } elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
                # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
-               $uts = strtotime( preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
-                               str_replace( '+00:00', 'UTC', $ts ) ) );
+               $strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
+                               str_replace( '+00:00', 'UTC', $ts ) );
        } elseif ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
                # TS_ISO_8601
        } elseif ( preg_match( '/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
@@ -2013,19 +2016,14 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
                # TS_DB2
        } elseif ( preg_match( '/^[A-Z][a-z]{2}, \d\d [A-Z][a-z]{2} \d{4} \d\d:\d\d:\d\d/', $ts ) ) {
                # TS_RFC2822
-               $uts = strtotime( $ts );
+               $strtime = $ts;
        } else {
                # Bogus value; fall back to the epoch...
                wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n");
                $uts = 0;
        }
 
-       if (count( $da ) ) {
-               // Warning! gmmktime() acts oddly if the month or day is set to 0
-               // We may want to handle that explicitly at some point
-               $uts = gmmktime( (int)$da[4], (int)$da[5], (int)$da[6],
-                       (int)$da[2], (int)$da[3], (int)$da[1] );
-       }
+       
 
        static $formats = array(
                TS_UNIX => 'U',
@@ -2044,12 +2042,37 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
                throw new MWException( 'wfTimestamp() called with illegal output type.' );
        }
 
-       if ( TS_UNIX == $outputtype ) {
-               return $uts;
+       if ( function_exists( "date_create" ) ) {
+               if ( count( $da ) ) {
+                       $ds = sprintf("%04d-%02d-%02dT%02d:%02d:%02d.00+00:00",
+                               (int)$da[1], (int)$da[2], (int)$da[3],
+                               (int)$da[4], (int)$da[5], (int)$da[6]);
+                       
+                       $d = date_create( $ds, new DateTimeZone( 'GMT' ) );
+               } else {
+                       $d = date_create( $strtime, new DateTimeZone( 'GMT' ) );
+               }
+               $output = $d->format( $formats[$outputtype] );
+       } else {
+               if ( count( $da ) ) {
+                       // Warning! gmmktime() acts oddly if the month or day is set to 0
+                       // We may want to handle that explicitly at some point
+                       $uts = gmmktime( (int)$da[4], (int)$da[5], (int)$da[6],
+                               (int)$da[2], (int)$da[3], (int)$da[1] );
+               } elseif ( $strtime ) {
+                       $uts = strtotime( $strtime );
+               }
+               
+               if ( $uts === false ) {
+                       return "Can't handle date";
+               }
+               
+               if ( TS_UNIX == $outputtype ) {
+                       return $uts;
+               }
+               $output = gmdate( $formats[$outputtype], $uts );
        }
 
-       $output = gmdate( $formats[$outputtype], $uts );
-
        if ( ( $outputtype == TS_RFC2822 ) || ( $outputtype == TS_POSTGRES ) ) {
                $output .= ' GMT';
        }